/******************************************************************
 * Created by: GOh CHee Hong                                      
 * Date of Creation: 1/Jan/2009            
 
 *                                                                
 * Description: This class is in charge of uploading a message
 ******************************************************************/

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.ComponentModel;
using System.Threading;
using Pbdms.Common.CryptoUtils;
using Pbdms.Common.SharedVariables;
using Org.BouncyCastle.Bcpg.OpenPgp;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Bcpg;
namespace Pbdms.BusinessLogic.Mail
{
    public class MessageUploader
    {
        
        
        private string friendKEYid;

        private string messageKey;
        private string password;
        public delegate void StatusHandler(object sender, string args);
        public StatusHandler statusProcess;
        public delegate Boolean checkCancel();
        public checkCancel isCancel;
        private MemoryStream memObj = null;
        public MessageUploader()
        {

        }
        ~MessageUploader()
        {
            if (memObj != null)
            {
                memObj.Close();
            }
        }

        public MessageUploader( string friend, string messageKey, MemoryStream memObj, string password)
        {
            
           
           
            this.friendKEYid = friend;
            this.messageKey = messageKey;
            this.memObj = memObj;
            this.password = password;
        }

        public Boolean PublishMessage()
        {
            string inboxKey = "";
            string inboxInformation = "";
            OpenDHTLib.OpenLookUp openDHT = new Pbdms.OpenDHTLib.OpenLookUp();
            try
            {

                //long size = memObj.Length;
                
                //uploading a mail arrival to recipient inbox
                inboxKey = friendKEYid + "'s Inbox";
                inboxInformation = messageKey + " Size:" + memObj.Length.ToString();                
                string Msg = "";
                //does not succeed send an mail invoice
                //calculate the numbers of blocks
                int blocks = Common.Global.CalculateNoOfBlocks(memObj.Length);
                //publish message information                
                //convert to byte array
                if (statusProcess != null)
                {
                    if (blocks > 1)
                    {
                        statusProcess(this, "Message is divided into " + blocks.ToString() + " blocks");
                        Thread.Sleep(1000);
                    }
                }
                int i = 0;
                int succed = 0;
                long size = 0;
                for (i=0; i<blocks; i++)
                {
                    if (isCancel != null)
                    {
                        if (isCancel() == true)
                        {
                            return false; ;
                        }
                    }
                    if ((memObj.Position + 1024) > memObj.Length)
                    {
                        size = memObj.Length-memObj.Position;
                    }
                    else
                    {
                        size = 1024;
                    }
                    byte[] data = new byte[size];
                    memObj.Read(data, 0, (int) size);
                    string key = messageKey + " Block No:" + i;
                    succed = openDHT.Put(key, data, 604800);                    
                    if (succed == 1)
                    {
                        Msg = "The network does not accept the block " + i + ". Over capacity occurred";
                    }
                    else if (succed == 2)
                    {
                        Msg = "An unknown error occurred while uploading block " + i + ". Please try again";
                    }
                    else if (succed == 0)
                    {
                        Msg = "Succeed in uploading block " + i;
                    }
                    if (statusProcess != null)
                    {
                        statusProcess(null, Msg);
                        Thread.Sleep(1000);
                    }

                    if (succed != 0)
                    {
                        return false;
                    }                  
                }                
                succed = openDHT.PutRemovable(inboxKey, inboxInformation, password, 604800);
                if (succed != 0)
                {

                    if (succed == 1)
                    {
                        Msg = "The network does not accept the message. Over capacity occurred";
                    }
                    else
                    {
                        Msg = "An unknown error occurred while sending. Please try again";
                    }
                    statusProcess(this, Msg);
                    Thread.Sleep(1000);
                    return false;
                }
                return true;
            }
            catch
            {
                if (statusProcess != null)
                {
                    statusProcess(null, "Error occurred in uploading message");
                    Thread.Sleep(1000);
                }
                return false;
            }
            finally
            {
                if (memObj != null)
                {
                    memObj.Close();
                }
                if (isCancel != null)
                {
                    if (isCancel() == true)
                    {
                        int i = openDHT.Rm(inboxKey, inboxInformation, password, 604800);
                    }
                }
            }
            
        }
    }
}
